/**
*      author: Y_Yao
*      created: 2024-10-16 09:12:38
**/

#include<bits/stdc++.h>

#define lc p<<1
#define rc p<<1|1
using namespace std;
using LL = long long;
const LL LLINF = 1e18;
const int INF = 0x3f3f3f3f;
const int N = 1e5 + 7;
LL a[N];
LL m;

struct node
{
    LL l,r,val,add,mul;
}tr[4 * N];

void pushup(LL p)
{   
    tr[p].val = (tr[lc].val + tr[rc].val) % m;
}

void pushdown(LL p)
{
    if(tr[p].add || tr[p].mul != 1)
    {
        tr[lc].val = (tr[lc].val * tr[p].mul + tr[p].add * (tr[lc].r - tr[lc].l + 1)) % m;
        tr[rc].val = (tr[rc].val * tr[p].mul + tr[p].add * (tr[rc].r - tr[rc].l + 1)) % m;

        tr[lc].add = (tr[lc].add * tr[p].mul + tr[p].add) % m;
        tr[rc].add = (tr[rc].add * tr[p].mul + tr[p].add) % m;

        tr[lc].mul = (tr[p].mul * tr[lc].mul) % m;
        tr[rc].mul = (tr[p].mul * tr[rc].mul) % m;

        tr[p].add = 0;
        tr[p].mul = 1;
    }
}

void build(LL p,LL l,LL r)
{
    tr[p] = {l,r,a[l] % m,0,1};
    if(l == r) return;

    LL mid = (l + r) >> 1;
    build(lc,l,mid);
    build(rc,mid + 1,r);
    pushup(p);
}

void update_add(LL p,LL x,LL y,LL k)
{
    if(x <= tr[p].l && tr[p].r <= y)
    {
        tr[p].val = (tr[p].val + (tr[p].r - tr[p].l + 1) * k) % m;
        tr[p].add = (tr[p].add + k) % m;
        return;
    }
    
    LL mid = (tr[p].l + tr[p].r) >> 1;
    pushdown(p);
    if(x <= mid) update_add(lc,x,y,k);
    if(y > mid) update_add(rc,x,y,k);
    pushup(p);
}

void update_mul(LL p,LL x,LL y,LL k)
{
    if(x <= tr[p].l && tr[p].r <= y)
    {
        tr[p].val = (tr[p].val * k) % m;
        tr[p].mul = (tr[p].mul * k) % m;
        tr[p].add = (tr[p].add * k) % m;
        return;
    }
    
    LL mid = (tr[p].l + tr[p].r) >> 1;
    pushdown(p);
    if(x <= mid) update_mul(lc,x,y,k);
    if(y > mid) update_mul(rc,x,y,k);
    pushup(p);
}

LL qurey(LL p,LL x,LL y)
{
    if(x <= tr[p].l && tr[p].r <= y)
    {
        return tr[p].val;
    }
    
    LL mid = (tr[p].l + tr[p].r) >> 1;
    pushdown(p);
    LL sum = 0;
    if(x <= mid) sum = (sum + qurey(lc,x,y)) % m;
    if(y > mid) sum = (sum + qurey(rc,x,y)) % m;
    return sum;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    LL n,q;
    cin >> n >> q >> m;
    for(LL i = 1;i <= n;i++)
    {
        cin >> a[i];
    }
    build(1,1,n);

    LL oper,x,y,k;
    while(q--)
    {
        cin >> oper;
        if(oper == 1)
        {
            cin >> x >> y >> k;
            update_mul(1,x,y,k);
        }
        else if(oper == 2)
        {
            cin >> x >> y >> k;
            update_add(1,x,y,k);
        }
        else
        {
            cin >> x >> y;
            LL out = qurey(1,x,y);
            cout << out << endl;
        }
    }
    return 0;
}